package com.example.prom.ok.y2022.service.taxbit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.example.prom.exception.ApiException;
import com.example.prom.ok.y2022.dto.taxbit.*;
import com.example.prom.ok.y2022.enums.ResponseErrorCodeEnum;
import com.example.prom.utils.HttpClientSingleton;
import com.example.prom.utils.HttpNewUtils;
import com.example.prom.utils.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.example.prom.ok.y2022.enums.ResponseErrorCodeEnum.SUCCESS;

@Slf4j
@Component
public class TaxBitService {

    private Map<String, String> map = new HashMap<>();
    private static final String KEY = "map";
    private static final String KEY2 = "map2";
    private static String baseUrl = "https://api.okcoin.enterprise-staging.taxbit.com/v1/";
    private static String clientId = "o9FnbFIGLVPwFDyCZ75REz91RxgkkSfX";
    private static String clientSecret = "LRPTEyHpV9lvuyGgYPRdljl4RiSd25UE6KDigXhFo3DcqdbMyhp2mmOq_dDgiWpK";

    public String getToken() {
        String accessToken = map.get(KEY);
        if (StringUtils.isNotEmpty(accessToken)) {
            log.info("TaxBitService getTokenFrom redis: {}", accessToken);
            return accessToken;
        }
        String token = "";
        try {
            String requestUrl = "https://api.okcoin.enterprise-staging.taxbit.com/v1/oauth/token";

            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();

            Map<String, String> queryMap = new HashMap<>();
            queryMap.put("client_id", "o9FnbFIGLVPwFDyCZ75REz91RxgkkSfX");
            queryMap.put("client_secret", "LRPTEyHpV9lvuyGgYPRdljl4RiSd25UE6KDigXhFo3DcqdbMyhp2mmOq_dDgiWpK");
            queryMap.put("grant_type", "client_credentials");

            HttpResponse httpResponse = HttpNewUtils.doPostByApplicationJson(requestUrl, null, httpClient, null, null, JSON.toJSONString(queryMap));
            String result = EntityUtils.toString(httpResponse.getEntity());

            TaxBitTokenRespDTO taxbitTokenRespDTO = JSON.parseObject(result, TaxBitTokenRespDTO.class);
            if (Objects.nonNull(taxbitTokenRespDTO)) {
                String access_token = taxbitTokenRespDTO.getAccess_token() == null ? "" : taxbitTokenRespDTO.getAccess_token();
                String token_type = taxbitTokenRespDTO.getToken_type() == null ? "" : taxbitTokenRespDTO.getToken_type();
                token = token_type + " " + access_token;
                map.put(KEY, token.trim());
            }
            log.info("TaxBitService getToken result:{} token:{}", result, token);

        } catch (Exception e) {
            log.error("TaxBitService getToken exception", e);
        }

        return token;
    }

    public JSONObject getExistingTaxBitUser(String tenantId, String userId){
        try {
            String token = getToken();
            String requestUrl = "https://api.okcoin.enterprise-staging.taxbit.com/v1/tenants/"+tenantId+"/users/"+userId;
            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("authorization",token);
            HttpResponse httpResponse = HttpNewUtils.doGet(requestUrl, null, httpClient, headerMap, null);
            String result = EntityUtils.toString(httpResponse.getEntity());
            Integer statusCode = httpResponse.getStatusLine().getStatusCode();
            JSONObject resultDTO = JSONObject.parseObject(result, JSONObject.class);
            log.info("TaxBitService getExistingTaxBitUser result:{}", result);
            if (statusCode == HttpStatus.SC_OK) {
                return resultDTO;
            } else {
                throw new ApiException("api接口异常");
            }
        } catch (Exception e){
            log.error("TaxBitService getToken exception", e);
            throw new ApiException("api接口异常");
        }
    }

    public ResponseResult updateTaxBitUser(String tenantId, String userId, TaxBitUserUpdateReqDTO taxBitUserUpdateReqDTO){
        try {
            String token = getToken();
            String requestUrl = baseUrl + "tenants/"+tenantId+"/users/"+userId;
            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("authorization",token);
            String body = JSON.toJSONString(taxBitUserUpdateReqDTO, SerializerFeature.WriteMapNullValue);
            HttpResponse httpResponse = HttpNewUtils.doPutByApplicationJSON(requestUrl, null, httpClient, headerMap, null, body);
            String result = EntityUtils.toString(httpResponse.getEntity());
            Integer statusCode = httpResponse.getStatusLine().getStatusCode();
            log.info("TaxBitService getExistingTaxBitUser result:{},tenantId:{},userId:{}", result, tenantId, userId);
            if (statusCode == HttpStatus.SC_OK) {
                GetTaxBitUserRespDTO resultDTO = JSONObject.parseObject(result, GetTaxBitUserRespDTO.class);
                return ResponseResult.build(SUCCESS, resultDTO);
            } else {
                JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);
                return ResponseResult.build(ResponseErrorCodeEnum.THIRD_RETURN_ERROR, jsonObject);
            }
        } catch (Exception e){
            log.error("TaxBitService updateTaxBitUser exception", e);
            return ResponseResult.build(ResponseErrorCodeEnum.INTERNAL_OTHER_EXCEPTION, null);
        }
    }

//    public ResponseResult documentRetrieve(){
//        try {
//            String token = "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1qRXpRamxETmpRd01ESkVORU16TVVFd1FUWTRRamRDTlRaRk5VSTFRVVV5TlVGQlJUQTNPUSJ9.eyJodHRwczovL3RheGJpdC5jb20vdGVuYW50LWlkIjoiY2JjNjY5OTYtMDI3OS00MWM1LWFiOTMtMWQwZTRiMjRkN2MyIiwiaHR0cHM6Ly90YXhiaXQuY29tL2FjY291bnQtb3duZXItaWQiOiJmYzcxYjIwMC1iMjkzLTQyNTUtODM3OS0yNTk5ZjA1ZjExNjgiLCJpc3MiOiJodHRwczovL2F1dGgudGF4Yml0LmNvbS8iLCJzdWIiOiJvOUZuYkZJR0xWUHdGRHlDWjc1UkV6OTFSeGdra1NmWEBjbGllbnRzIiwiYXVkIjoidGF4Yml0LWludGVybmFsIiwiaWF0IjoxNjcxNTg4MTQ0LCJleHAiOjE2NzE2NzQ1NDQsImF6cCI6Im85Rm5iRklHTFZQd0ZEeUNaNzVSRXo5MVJ4Z2trU2ZYIiwic2NvcGUiOiJyZWFkOmNvaW5zIHJlYWQ6dGF4cHJvZmlsZXMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMiLCJwZXJtaXNzaW9ucyI6WyJyZWFkOmNvaW5zIiwicmVhZDp0YXhwcm9maWxlcyJdfQ.ewP6FtE1vLEV1jW2Ws6IsJbC40xz-s7qjLcLq7hk-TQRRH-EkBZpWwRQR1jueh3LIYFhtD_UhkCcf195h0_AIwVjHe-q9Tv1Qg69y0NH9WrvRUIzwfeheMdYsr61XBQdwaX2SPT8YkSd-Qa6bixR3knu5N_NHvnG-HvTQaViUOe4ofacogPb5Qifj2NDOB876yX8mMKK-cQB5bZguNDifGWYbnhjG-4xfanJMSqMLW2w2L6Pf9yeq-PD_kr_IOK-o257NPpNezeKIcpeEq_OJInstEog63i_gjDvUkdp-s0gRpi0GtxCLiBE9TUsrcvTxz3rqCLjMFB1VKsW5PHwTQ";
//            String requestUrl = baseUrl + "tax-documentation/w-9";
//
//            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();
//            Map<String, String> headerMap = new HashMap<>();
//            headerMap.put("authorization",token);
//            HttpResponse httpResponse = HttpNewUtils.doGet(requestUrl, null, httpClient, headerMap, null);
//            String result = EntityUtils.toString(httpResponse.getEntity());
//            Integer statusCode = httpResponse.getStatusLine().getStatusCode();
//            log.info("TaxBitService getExistingTaxBitUser result:{}", result);
//            if (statusCode == HttpStatus.SC_OK) {
//                TaxBitDocRetrieveRespDTO resultDTO = JSONObject.parseObject(result, TaxBitDocRetrieveRespDTO.class);
//                return ResponseResult.build(SUCCESS, resultDTO);
//            } else {
//                JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);
//                return ResponseResult.build(ResponseErrorCodeEnum.THIRD_RETURN_ERROR, jsonObject);
//            }
//        } catch (Exception e){
//            log.error("TaxBitService updateTaxBitUser exception", e);
//            return ResponseResult.build(ResponseErrorCodeEnum.INTERNAL_OTHER_EXCEPTION, null);
//        }
//    }
    public ResponseResult taxDocumentRetrieve(HttpServletRequest request){
        String result = "";
        try {
            String requestUrl = baseUrl + "tax-documentation/w-9";

            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("authorization", request.getHeader("authorization"));
            HttpResponse httpResponse = HttpNewUtils.doGet(requestUrl, null, httpClient, headerMap, null);
            result = EntityUtils.toString(httpResponse.getEntity());
            Integer statusCode = httpResponse.getStatusLine().getStatusCode();
            TaxBitDocRetrieveRespDTO resultDTO = JSONObject.parseObject(result, TaxBitDocRetrieveRespDTO.class);
            log.info("TaxBitService taxDocumentRetrieve result:{},resultDTO:{}", result,resultDTO);
            if (statusCode == HttpStatus.SC_OK) {
                return ResponseResult.build(SUCCESS, resultDTO);
            } else {
                return ResponseResult.build(ResponseErrorCodeEnum.THIRD_RETURN_ERROR, resultDTO);
            }
        } catch (Exception e){
            log.error("TaxBitService taxDocumentRetrieve exception", e);
            TaxBitDocRetrieveRespDTO resultDTO = new TaxBitDocRetrieveRespDTO();
            resultDTO.setMessage(result);
            return ResponseResult.build(ResponseErrorCodeEnum.INTERNAL_OTHER_EXCEPTION, resultDTO);
        }
    }

    public ResponseResult documentSubmit(Map<String, Object> map){

        try {
            String token = "Bearer                    eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1qRXpRamxETmpRd01ESkVORU16TVVFd1FUWTRRamRDTlRaRk5VSTFRVVV5TlVGQlJUQTNPUSJ9.eyJodHRwczovL3RheGJpdC5jb20vdGVuYW50LWlkIjoiY2JjNjY5OTYtMDI3OS00MWM1LWFiOTMtMWQwZTRiMjRkN2MyIiwiaHR0cHM6Ly90YXhiaXQuY29tL2FjY291bnQtb3duZXItaWQiOiJmYzcxYjIwMC1iMjkzLTQyNTUtODM3OS0yNTk5ZjA1ZjExNjgiLCJpc3MiOiJodHRwczovL2F1dGgudGF4Yml0LmNvbS8iLCJzdWIiOiJvOUZuYkZJR0xWUHdGRHlDWjc1UkV6OTFSeGdra1NmWEBjbGllbnRzIiwiYXVkIjoidGF4Yml0LWludGVybmFsIiwiaWF0IjoxNjcxNTg4MTQ0LCJleHAiOjE2NzE2NzQ1NDQsImF6cCI6Im85Rm5iRklHTFZQd0ZEeUNaNzVSRXo5MVJ4Z2trU2ZYIiwic2NvcGUiOiJyZWFkOmNvaW5zIHJlYWQ6dGF4cHJvZmlsZXMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMiLCJwZXJtaXNzaW9ucyI6WyJyZWFkOmNvaW5zIiwicmVhZDp0YXhwcm9maWxlcyJdfQ.ewP6FtE1vLEV1jW2Ws6IsJbC40xz-s7qjLcLq7hk-TQRRH-EkBZpWwRQR1jueh3LIYFhtD_UhkCcf195h0_AIwVjHe-q9Tv1Qg69y0NH9WrvRUIzwfeheMdYsr61XBQdwaX2SPT8YkSd-Qa6bixR3knu5N_NHvnG-HvTQaViUOe4ofacogPb5Qifj2NDOB876yX8mMKK-cQB5bZguNDifGWYbnhjG-4xfanJMSqMLW2w2L6Pf9yeq-PD_kr_IOK-o257NPpNezeKIcpeEq_OJInstEog63i_gjDvUkdp-s0gRpi0GtxCLiBE9TUsrcvTxz3rqCLjMFB1VKsW5PHwTQ";
            String requestUrl = baseUrl + "tax-documentation/w-9";

            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("authorization",token);
            HttpResponse httpResponse = HttpNewUtils.doPostByApplicationJson(requestUrl, null, httpClient, headerMap, null, JSON.toJSONString(map));
            String result = EntityUtils.toString(httpResponse.getEntity());
            Integer statusCode = httpResponse.getStatusLine().getStatusCode();
            log.info("TaxBitService getExistingTaxBitUser result:{}", result);
            if (statusCode == HttpStatus.SC_OK) {
                JSONObject resultDTO = JSONObject.parseObject(result, JSONObject.class);
                return ResponseResult.build(SUCCESS, resultDTO);
            } else {
                JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);
                return ResponseResult.build(ResponseErrorCodeEnum.THIRD_RETURN_ERROR, jsonObject);
            }
        } catch (Exception e){
            log.error("TaxBitService updateTaxBitUser exception", e);
            return ResponseResult.build(ResponseErrorCodeEnum.INTERNAL_OTHER_EXCEPTION, null);
        }
    }

    public ResponseResult createAccountOwner(String tenantId, CreateAccountOwnerReqDTO reqDTO){
        try {
            String token = getToken();
            String requestUrl = baseUrl + "/tenants/"+tenantId+"/account-owners";

            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("authorization",token);
            HttpResponse httpResponse = HttpNewUtils.doPostByApplicationJson(requestUrl, null, httpClient, headerMap, null, JSON.toJSONString(reqDTO));
            String result = EntityUtils.toString(httpResponse.getEntity());
            Integer statusCode = httpResponse.getStatusLine().getStatusCode();
            JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);
            log.info("TaxBitService getExistingTaxBitUser result:{}", result);
            if (statusCode == HttpStatus.SC_OK) {
                return ResponseResult.build(SUCCESS, jsonObject);
            } else {
                return ResponseResult.build(ResponseErrorCodeEnum.THIRD_RETURN_ERROR, jsonObject);
            }
        } catch (Exception e){
            log.error("TaxBitService updateTaxBitUser exception", e);
            return ResponseResult.build(ResponseErrorCodeEnum.INTERNAL_OTHER_EXCEPTION, null);
        }
    }

    public ResponseResult getAccountOwner(String tenantId, String externalId){
        try {
            String token = getToken();
            String requestUrl = baseUrl + "/tenants/"+tenantId+"/account-owners";

            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("authorization",token);

            Map<String, String> queryMap = new HashMap<>();
            queryMap.put("external_id",externalId);
            HttpResponse httpResponse = HttpNewUtils.doGet(requestUrl, null, httpClient, headerMap, queryMap);
            String result = EntityUtils.toString(httpResponse.getEntity());
            Integer statusCode = httpResponse.getStatusLine().getStatusCode();
            JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);
            log.info("TaxBitService getExistingTaxBitUser result:{}", result);
            if (statusCode == HttpStatus.SC_OK) {
                return ResponseResult.build(SUCCESS, jsonObject);
            } else {
                return ResponseResult.build(ResponseErrorCodeEnum.THIRD_RETURN_ERROR, jsonObject);
            }
        } catch (Exception e){
            log.error("TaxBitService updateTaxBitUser exception", e);
            return ResponseResult.build(ResponseErrorCodeEnum.INTERNAL_OTHER_EXCEPTION, null);
        }
    }

    public ResponseResult getAccountOwnerToken(String tenantId, String accountOwnerId) {
        log.info("TaxBitService getAccountOwnerToken params tenantId:{} accountOwnerId:{}", tenantId, accountOwnerId);
        TaxBitAccountOwnerTokenDTO tokenDTO = new TaxBitAccountOwnerTokenDTO();
        String token = "";
        String result = "";
        try {
            String accessToken = map.get(KEY2);
            if (StringUtils.isNotEmpty(accessToken)) {
                log.info("TaxBitService getTokenFrom redis: {}", accessToken);
                tokenDTO.setToken(accessToken);
                return ResponseResult.build(SUCCESS, tokenDTO);
            }
            String requestUrl = baseUrl + "oauth/account-owner-token";

            HttpClient httpClient = HttpClientSingleton.getLongCustomHttpClient();

            Map<String, String> queryMap = new HashMap<>();
            queryMap.put("client_id", clientId);
            queryMap.put("client_secret", clientSecret);
            queryMap.put("grant_type", "client_credentials");
            if (StringUtils.isNotEmpty(tenantId)) {
                queryMap.put("tenant_id", tenantId);
            }
            if (StringUtils.isNotEmpty(accountOwnerId)) {
                queryMap.put("account_owner_id", accountOwnerId);
            }
            HttpResponse httpResponse = HttpNewUtils.doPostByForm(requestUrl, null, httpClient, null, null, queryMap);
            result = EntityUtils.toString(httpResponse.getEntity());
            TaxBitTokenRespDTO taxbitTokenRespDTO = JSON.parseObject(result, TaxBitTokenRespDTO.class);
            if (Objects.nonNull(taxbitTokenRespDTO)) {
                String access_token = taxbitTokenRespDTO.getAccess_token();
                access_token = StringUtils.isEmpty(access_token) ? "" : access_token;
                String token_type = taxbitTokenRespDTO.getToken_type();
                token_type = StringUtils.isEmpty(token_type) ? "" : token_type;
                token = token_type + " " + access_token;
                map.put(KEY2, token.trim());
                tokenDTO.setToken(token);
            }
            log.info("TaxBitService getAccountOwnerToken result:{} token:{}", result, token);

        } catch (Exception e) {
            log.error("TaxBitService getAccountOwnerToken exception", e);
            tokenDTO.setErrorMessage(result);
            return ResponseResult.build(ResponseErrorCodeEnum.INTERNAL_OTHER_EXCEPTION, tokenDTO);
        }
        return ResponseResult.build(SUCCESS, tokenDTO);
    }

    public String testGet(String id){
        return "id-"+id;
    }

    public CreateAccountOwnerReqDTO testPost(CreateAccountOwnerReqDTO reqDTO){
        return reqDTO;
    }
}